// scripts/extractAndInject.ts
import fs from 'fs'
import path from 'path'

type ExtractorOptions = {
    name?: string
    ext: string
    globalVar: string
    injectMarker: string
    inputDir: string
    outputFile: string
    htmlFilePath?: string // 可选：默认 .vitepress/dist/index.html
}

function waitForFile(
    filePath: string,
    timeout = 10000,
    interval = 300
): Promise<void> {
    return new Promise((resolve, reject) => {
        const start = Date.now()

        const timer = setInterval(() => {
            if (fs.existsSync(filePath)) {
                clearInterval(timer)
                resolve()
            } else if (Date.now() - start > timeout) {
                clearInterval(timer)
                reject(new Error(`等待文件 ${filePath} 超时`))
            }
        }, interval)
    })
}

function readFiles(dir: string, ext: string, projectRoot: string): any[] {
    if (!fs.existsSync(dir)) return []

    const entries = fs.readdirSync(dir, { withFileTypes: true })

    return entries.flatMap(entry => {
        const fullPath = path.join(dir, entry.name)
        return entry.isDirectory()
            ? readFiles(fullPath, ext, projectRoot)
            : entry.name.endsWith(ext)
                ? {
                    path: path.relative(projectRoot, fullPath),
                    content: fs.readFileSync(fullPath, 'utf-8')
                }
                : []
    })
}

export async function extractAndInject(options: ExtractorOptions) {
    const {
        name = 'content-extractor',
        ext,
        globalVar,
        injectMarker,
        inputDir,
        outputFile,
        htmlFilePath = '.vitepress/dist/index.html'
    } = options

    const projectRoot = process.cwd()
    const inputDirFullPath = path.resolve(projectRoot, inputDir)
    const contents = readFiles(inputDirFullPath, ext, projectRoot)

    const jsContent = `window.${globalVar} = ${JSON.stringify(
        Object.fromEntries(contents.map(item => [item.path, item.content])),
        null,
        2
    )}`

    const outputFullPath = path.resolve(projectRoot, outputFile)
    fs.mkdirSync(path.dirname(outputFullPath), { recursive: true })
    fs.writeFileSync(outputFullPath, jsContent)

    const htmlPath = path.resolve(projectRoot, htmlFilePath)

    try {
        await waitForFile(htmlPath, 10000)
        let html = fs.readFileSync(htmlPath, 'utf-8')

        if (!html.includes(injectMarker)) {
            const scriptPath = path.relative(
                path.resolve(projectRoot, '.vitepress/dist'),
                outputFullPath
            )

            html = html.replace(
                '</head>',
                `${injectMarker}\n<script src="/${scriptPath}"></script>\n</head>`
            )

            fs.writeFileSync(htmlPath, html)
            console.log(`[${name}] ✅ 成功注入 <script src="/${scriptPath}">`)
        } else {
            console.log(`[${name}] ⏩ 已存在注入标记，跳过`)
        }

        console.log(`[${name}] ✅ 全部处理完成`)
    } catch (e: any) {
        console.warn(`[${name}] ❌ ${e.message}`)
    }
}
